#include "cstring.h"

CString::CString() : length_(0), data_(nullptr) {
}

/**
 * 核心实现函数，其他构造构造函数和赋值函数都是调用的这个函数
 * 空字符串也包含 '\0'
*/
void CString::build(const char* str, const size_t len) {
    if (str == nullptr || len == 0) {
        length_ = 0;
        data_ = new char[1];
        data_[0] = '\0';
        return;
    }
    length_ = len;
    data_ = new char[length_ + 1];
    strcpy(data_, str);
}
CString::CString(const char* str) {
    build(str, strlen(str));
}

CString::CString(const CString& str) {
    build(str.data_, str.length_);
}

CString& CString::operator=(const char* str) {
    build(str, strlen(str));
    return *this;
}

CString& CString::operator=(const CString& str) {
    build(str.data_, str.length_);
    return *this;
}

CString& CString::append(const char* str, const size_t len) {
    length_ += len;
    char* new_data = new char[length_ + 1];
    strcpy(new_data, data_);
    strcat(new_data, str);
    delete[] data_; //删除原来的数据
    data_ = new_data;
    return *this;
}

CString& CString::append(const char* str) {
    return append(str, strlen(str));
}

CString& CString::append(const CString& str) {
    return append(str.data_, str.length_);
}

CString CString::add(const char* str, const size_t len) {
    char* new_data = new char[length_ + len + 1];
    strcpy(new_data, data_);
    strcat(new_data, str);
    CString res(new_data);
    delete[] new_data; //删除临时new的数组
    return res;
}

CString CString::operator+(const char* str) {
    return add(str, strlen(str));
}

CString CString::operator+(const CString& str) {
    return add(str.data_, str.length_);
}

char& CString::operator[](size_t index) {
    return data_[index];
}

CString::~CString() {
    delete[] data_;
}

char* CString::strcpy(char *dst, const char *src) {
    if (dst == nullptr || src == nullptr) {
        return dst;
    }
    int len = strlen(src);
    for (size_t i = 0; i < len; ++i) {
        dst[i] = src[i];
    }
    dst[length_] = '\0';
}

char* CString::strcat(char *dst, const char *src) {
    if (dst == nullptr || src == nullptr) {
        return dst;
    }
    int dst_len = strlen(dst);
    int src_len = strlen(src);
    for (size_t i = 0; i < src_len; ++i) {
        dst[dst_len + i] = src[i];
    }
    dst[dst_len + src_len] = '\0';
}

size_t CString::strlen(const char *str) {
    if (str == nullptr) {
        return 0;
    }
    size_t len = 0;
    while (str[len] != '\0') {
        ++len;
    }
    return len;
}

size_t CString::length() const {
    return length_;
}

const char* CString::data() const {
    return data_;
}

std::ostream& operator<<(std::ostream& os, const CString& str) {
    os << str.data_;
    return os;
}

